package com.sfx.concurrent.demo.concurrent.pattern.GuardedObjectEncapsulationTest;

/**
 * Created with IntelliJ IDEA.
 * Description: 每一家的小邮箱
 * User: sfx
 * Date: 2023-01-01
 * Time: 10:26
 */
//带有时限的
public class GuardedObject {

    private int id; //用于唯一标识每家的邮箱

    private Object response;//相当于信封-->相互传递的结果

    public GuardedObject(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }

    /**
     * 获取信封
     * 获取信封的时间就是timeout,超出timeout就不等了
     * @param timeout
     * @return
     */
    public Object get(long timeout) {
        long begin = System.currentTimeMillis();//获取到开始获取信封的时间
        long passTime = 0;//经历的时间
        synchronized(this) {
            while(response==null){//信封不存在就一直在这等
                if(passTime>=timeout){//超出等待时间不等了
                    break;
                }
                try {
                    //这里一定要等待timeout - passTime s 才是真正一轮等待的时间
                    //如果是timeout 发生了虚假唤醒 再次执行while就会在等待2s
                    this.wait(timeout - passTime);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //经过的时间计算
                passTime = System.currentTimeMillis() - begin;
            }
            //信封不为空就立即返回
            return response;
        }
    }

    /**
     * 产生信封
     * @param response
     */
    public void complete(Object response) {
        synchronized (this) {
            this.response = response;
            this.notifyAll();//唤醒正在等待的线程,已经有值了
        }
    }
}